/*
 * Database abstraction for handling connection logic
 */
package healthcare;

import java.sql.*;

/**
 * Consolidates connection configuration and initiation of connections to database. 
 * The code must be able to connect to arbitrary (eg. localhost/towson) databases
 * 
 * @author Doug Keeley
 */
public class HealthcareDatabase {
    
    //private static Connection connection = null;
    private String dbDriverClass = "oracle.jdbc.driver.OracleDriver";
    private String dbDriverPrefix = "jdbc:oracle:thin:";
    private String dbHost = "@localhost";
    private String dbPort = "1521";
    private String dbSsid = "";
    private String dbUsername = "hdcp1";
    private String dbPassword = "h3llo";
    
    
    /**
     * configure database for connection to default database.  Uses default dev values
     */
    public HealthcareDatabase() throws Exception {
        
        //not sure if this should be tested here.  Maybe calling code should contain logic
        if (testDatabaseConnection()) {
            System.out.println("HdcpDatabase.HdcpDatabase(): created database"); 
        } else {
            System.out.println("HdcpDatabase.HdcpDatabase(): failed to creat database"); 
            throw new Exception("HdcpDatabase.HdcpDatabase(): failed to creat database");
        }
    }
     
    /**
     * configure database for connection to arbitrary database
     */    
    public HealthcareDatabase(String dbHost, String dbPort, String dbUsername, String dbPassword) throws Exception {

        //this.dbDriverClass = dbDriverClass;    //assume oracle
        //this.dbDriverPrefix = dbDriverPrefix;  //assume oracle
        this.dbHost = dbHost;
        this.dbPort = dbPort;
        //this.dbSsid = dbSsid;      //assume no database/ssid/tablespace.  May need to set default tablespace for user
        this.dbUsername = dbUsername;
        this.dbPassword = dbPassword;
        
        //not sure if this should be tested here.  Maybe calling code should contain logic
        if (testDatabaseConnection()) {
            System.out.println("HdcpDatabase.HdcpDatabase(): created database"); 
        } else {
            System.out.println("HdcpDatabase.HdcpDatabase(): failed to creat database"); 
            throw new Exception("HdcpDatabase.HdcpDatabase(): failed to creat database");
        }
    }
    
    /**
     * test the database connection.
     * This code should be changed to test access to a project-specific table.  
     * - Should code just rely on exceptions to indicate failure/success?  Or both 'true' and not-exception?
     * 
     * @return true if connection was tested ok; false if not
     */
    public boolean testDatabaseConnection()  {
        boolean connectedToDatabase = false;
        boolean connectedToData = false;
        
        try {
            Connection conn = getConnection();
            connectedToDatabase = true;  //redundant??
            
            Statement stmt =  conn.createStatement();
            ResultSet rs = stmt.executeQuery("select count(*) from CareGiver");
            connectedToData = true;

            System.out.println("HdcpDatabase.testDatabaseConnection(): database test succeeded; found correct database");
        }
        catch (Exception e) {    //need to clarify what exception we're looking for - SqlException??
            //connectedOk remains false
            System.out.println("HdcpDatabase.testDatabaseConnection(): database test failed with exception: " + e); 
            //should we re-throw exception??
        } 
        
        return (connectedToDatabase && connectedToData);   
    }
  
    
    public Connection getConnection()  {
        
        Connection connection = null;
        
        try {
            Class.forName(dbDriverClass);  //make sure classpath includes oracle driver (eg: ojdbc6_g.jar)
            String dbConnectionString = dbDriverPrefix + ":" +
                                        dbHost + ":" +
                                        dbPort + ":";  // +
                                        //dbSsid + ":"
            
            System.out.println("HdcpDatabase.getConnection(): creating connection [" + 
                                        dbConnectionString + ", " + dbUsername + ", " + dbPassword + "]...");
            
            //original code
            //Class.forName("oracle.jdbc.driver.OracleDriver");  //you will get error here if classpath isn't set properly
            //Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521", "doug2","h3llo");  //last params is uname/password

            connection = DriverManager.getConnection(dbConnectionString, dbUsername, dbPassword);
           
            System.out.println("HdcpDatabase.getConnection(): successfully opened connection");
        }
        catch (SQLException e) {  
            System.out.println("HdcpDatabase.getConnection(): failed to create connection. " + e);
        } 
        catch (ClassNotFoundException e) {  
            System.out.println("HdcpDatabase.getConnection(): failed to find driver class [" + dbDriverClass + "] " + e);
        } 
        return connection;
        
    }  //getConnection()
    
}  //HdcpDatabase
